﻿using System;
using System.Data;
using System.Web.Mvc;
using Google.GData.Analytics;
using GuRenFang.Service.Entity;

namespace GuRenFang.Controllers.Management
{
    public class StatisticsController : Controller
    {
        private const String CLIENT_USERNAME = "ghx02203@gmail.com";
        private const String CLIENT_PASS = "ghx02203@163.com";
        private const String TABLE_ID = "ga:50882140";

        [Authorize]
        public ActionResult Default(string startDay = "", string endDay = "")
        {
            DateTime _endday;
            DateTime _startday = GetStartday(startDay, endDay, out _endday);

            ViewBag.Model = "Statistics";
            // Configure GA API.
            DataFeed feed = GetFeed(_startday, _endday, "ga:visitorType",
                                    "ga:visits,ga:newVisits,ga:percentNewVisits,ga:avgTimeOnSite,ga:pageviews,ga:visitBounceRate",
                                    5, "");
            StatisticsData statisticsData = GetStatisticsData(feed);

            DataFeed sourceFeed = GetFeed(_startday, _endday, "ga:medium", "ga:visits", 5, "");

            DataTable dt = GetTrafficSources(sourceFeed);
            statisticsData.FromDirect = int.Parse(dt.Rows[0][1].ToString());
            statisticsData.FromRecommand = int.Parse(dt.Rows[1][1].ToString());
            statisticsData.FromSearchEngine = int.Parse(dt.Rows[2][1].ToString());
            return View(statisticsData);
        }

        [Authorize]
        public ActionResult KeyWordsData(string startDay = "", string endDay = "")
        {
            DateTime _endday;
            DateTime _startday = GetStartday(startDay, endDay, out _endday);
            ViewBag.Title = "搜索关键字";
            ViewBag.Action = "KeyWordsData";
            ViewBag.Model = "Statistics";

            DataFeed sourceFeed = GetFeed(_startday, _endday, "ga:keyword",
                                          "ga:visits,ga:percentNewVisits,ga:pageviews,ga:avgTimeOnSite,ga:visitBounceRate",
                                          800, "-ga:visits");

            DataTable dt = GetTrafficSources(sourceFeed);

            return View("Details", dt);
        }

        [Authorize]
        public ActionResult SourceData(string startDay = "", string endDay = "")
        {
            DateTime _endday;
            DateTime _startday = GetStartday(startDay, endDay, out _endday);
            ViewBag.Title = "流量来源";
            ViewBag.Action = "SourceData";
            ViewBag.Model = "Statistics";
            DataFeed sourceFeed = GetFeed(_startday, _endday, "ga:source",
                                          "ga:visits,ga:percentNewVisits,ga:pageviews,ga:avgTimeOnSite,ga:visitBounceRate",
                                          800, "-ga:visits");

            DataTable dt = GetTrafficSources(sourceFeed);

            return View("Details", dt);
        }

        [Authorize]
        public ActionResult BrowserData(string startDay = "", string endDay = "")
        {
            DateTime _endday;
            DateTime _startday = GetStartday(startDay, endDay, out _endday);
            ViewBag.Title = "访问者浏览器";
            ViewBag.Action = "BrowserData";
            ViewBag.Model = "Statistics";
            DataFeed sourceFeed = GetFeed(_startday, _endday, "ga:browser",
                                          "ga:visits,ga:percentNewVisits,ga:pageviews,ga:avgTimeOnSite,ga:visitBounceRate",
                                          800, "-ga:visits");

            DataTable dt = GetTrafficSources(sourceFeed);

            return View("Details", dt);
        }

        [Authorize]
        public ActionResult CityData(string startDay = "", string endDay = "")
        {
            DateTime _endday;
            DateTime _startday = GetStartday(startDay, endDay, out _endday);
            ViewBag.Title = "访问者城市";
            ViewBag.Action = "CityData";
            ViewBag.Model = "Statistics";
            DataFeed sourceFeed = GetFeed(_startday, _endday, "ga:city",
                                          "ga:visits,ga:percentNewVisits,ga:pageviews,ga:avgTimeOnSite,ga:visitBounceRate",
                                          800, "-ga:visits");

            DataTable dt = GetTrafficSources(sourceFeed);

            return View("Details", dt);
        }

        [Authorize]
        public ActionResult ServiceProviderData(string startDay = "", string endDay = "")
        {
            DateTime _endday;
            DateTime _startday = GetStartday(startDay, endDay, out _endday);
            ViewBag.Title = "访问者网络";
            ViewBag.Action = "ServiceProviderData";
            ViewBag.Model = "Statistics";
            DataFeed sourceFeed = GetFeed(_startday, _endday, "ga:networkLocation",
                                          "ga:visits,ga:percentNewVisits,ga:pageviews,ga:avgTimeOnSite,ga:visitBounceRate",
                                          800, "-ga:visits");

            DataTable dt = GetTrafficSources(sourceFeed);

            return View("Details", dt);
        }

        private DateTime GetStartday(string startDay, string endDay, out DateTime _endday)
        {
            DateTime dtNow = DateTime.Now;
            _endday = dtNow.AddDays(-1);
            DateTime _startday = dtNow.AddDays(-1).AddMonths(-1);

            if (!string.IsNullOrEmpty(startDay))
            {
                _startday = Convert.ToDateTime(startDay);
            }
            if (!string.IsNullOrEmpty(endDay))
            {
                _endday = Convert.ToDateTime(endDay);
            }

            ViewBag.StartDay = _startday.ToString("yyyy-MM-dd");
            ViewBag.EndDay = _endday.ToString("yyyy-MM-dd");
            return _startday;
        }

        private StatisticsData GetStatisticsData(DataFeed feed)
        {
            Aggregates aggregates = feed.Aggregates;
            var statisticsData = new StatisticsData();
            foreach (Metric metric in aggregates.Metrics)
            {
                if (metric.Name == "ga:visits")
                    statisticsData.Visits = int.Parse(metric.Value);
                else if (metric.Name == "ga:newVisits")
                    statisticsData.NewVisits = int.Parse(metric.Value);
                else if (metric.Name == "ga:percentNewVisits")
                    statisticsData.PercentNewVisits = double.Parse(metric.Value);
                else if (metric.Name == "ga:avgTimeOnSite")
                    statisticsData.AvgTimeOnSite = new DateTime((long) (10000000*double.Parse(metric.Value)));
                else if (metric.Name == "ga:pageviews")
                    statisticsData.Pageviews = int.Parse(metric.Value);
                else if (metric.Name == "ga:visitBounceRate")
                    statisticsData.VisitBounceRate = double.Parse(metric.Value);
            }
            return statisticsData;
        }

        private DataTable GetTrafficSources(DataFeed feed)
        {
            var dtReturn = new DataTable();
            if (feed.Entries.Count == 0)
            {
                return dtReturn;
            }
            int i = 0;
            foreach (DataEntry entry in feed.Entries)
            {
                if (i == 0)
                {
                    // Put all the dimension and metric names into an array.
                    foreach (Dimension dimension in entry.Dimensions)
                    {
                        dtReturn.Columns.Add(dimension.Name);
                    }
                    foreach (Metric metric in entry.Metrics)
                    {
                        dtReturn.Columns.Add(metric.Name);
                    }
                }
                DataRow dr = dtReturn.NewRow();
                foreach (Dimension dimension in entry.Dimensions)
                {
                    dr[dimension.Name] = dimension.Value;
                }
                foreach (Metric metric in entry.Metrics)
                {
                    dr[metric.Name] = metric.Value;
                }
                dtReturn.Rows.Add(dr);
                i++;
            }

            return dtReturn;
        }

        private DataFeed GetFeed(DateTime _startday, DateTime _endday, string dimensions, string metrics,
                                 int numberToRetrieve, string sort)
        {
            var asv = new AnalyticsService("gurenfang.net");
            // Client Login Authorization.
            asv.setUserCredentials(CLIENT_USERNAME, CLIENT_PASS);
            // GA Data Feed query uri.
            String baseUrl = "https://www.google.com/analytics/feeds/data";
            var query = new DataQuery(baseUrl);
            query.Ids = TABLE_ID;
            query.Dimensions = dimensions;
            query.Metrics = metrics;
            query.Sort = sort;
            query.NumberToRetrieve = numberToRetrieve;
            query.GAStartDate = _startday.ToString("yyyy-MM-dd");
            query.GAEndDate = _endday.ToString("yyyy-MM-dd");
            Uri url = query.Uri;
            return asv.Query(query);
        }
    }
}
